import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import util.Config;

/**
 * Doraemon
 */
public class Doraemon {
    private Map<String, List<String>> configMap;
    private String hwDir;
    private Random rnd;

    /**
     * 构造方法
     * 
     * @param configFile 用于指定配置文件，以供哆啦A梦了解评分细则
     * @param hwDir      用于指定作业存放目录
     */
    public Doraemon(String configFile, String hwDir) {
        this.configMap = Config.getConfig(configFile);
        this.hwDir = hwDir;
        this.rnd = new Random(114514);
    }

    /**
     * 写评语
     * 
     * @param hwName 用于指定是给哪一次作业写评语<br>
     *               可以采用 `hw-1` 或者 `hw-{1:100}`的形式
     * @return 返回值是一个字典<br>
     *         键以 `hw-20210001-中野一花`的形式<br>
     *         纠正：键应该是以`hw/20210001-中野一花/hw-1`的形式<br>
     *         值为评语字符串，其中包含了换行
     */
    public Map<String, String> writeComment(String hwName) {
        List<String> hwNameList = this.compileHwList(hwName);
        Map<String, String> comments = new HashMap<>();
        File path = new File(hwDir);
        //变量建议使用驼峰式命名，此处可改为localHwName
        for (String localhwName : hwNameList) {
            for (File p : path.listFiles()) {
                String idAndName = p.getName();
                String key = this.hwDir + File.separator + idAndName + File.separator + localhwName;
                String value = this.generateContent();
                comments.put(key, value);
            }
        }

        return comments;
    }

    /**
     * 生成评语
     * 
     * @return 返回值是一个同学一次的所有评语<br>
     *         根据not-late-ratio（提交作业不为空的概率）、base-ratio（实现某条基本功能的概率）<br>
     *            positive-ratio（实现某条加分点的概率）、negative-ratio（实现某条扣分点的概率）<br>
     *        通过随机数完成对一个同学一次作业的评语
     */
    private String generateContent() {
        if (this.random(this.configMap.get("not-late-ratio").get(0)) == false) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (String s : new String[] { "base", "positive", "negative" }) {
            for (String baseItem : this.configMap.get(s + "-item-list")) {
                if (this.random(this.configMap.get(s + "-ratio").get(0)) == false) {
                    continue;
                }
                String line = this.configMap.get(s + "-prefix").get(0) + " " + baseItem;
                sb.append(line + "\n");
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    private Boolean random(String ratio) {
        Double r = Double.parseDouble(ratio);
        return this.rnd.nextDouble() <= r;
    }

    /**
     * 解析`hw-{1:100}`形式的作业名称
     * 
     * @param hwName
     * @return 返回值为形如"hw-1"、"hw-2"、"hw-3"、...、"hw-100"的List<String>
     */
    private List<String> compileHwList(String hwName) {
        List<String> hwNameList = new ArrayList<>();
        Pattern pattern = Pattern.compile("hw-\\{(\\d+):(\\d+)\\}");
        //以pattern的正则表达式匹配hwName字符串
        Matcher matcher = pattern.matcher(hwName);
        if (matcher.matches()) {
            int a = Integer.parseInt(matcher.group(1));
            int b = Integer.parseInt(matcher.group(2));
            for (int i = a; i <= b; i++) {
                hwNameList.add("hw-" + i);
            }
        } else {
            hwNameList.add(hwName);
        }
        return hwNameList;
    }

    /**
     * configMap的get函数
     * @author ethan
     * @date 2021/7/10 15:48
     * @return java.util.Map<java.lang.String,java.util.List<java.lang.String>>
     */
    public Map<String, List<String>> getConfigMap()
    {
        return this.configMap;
    }

    public static void main(String[] args) {
        // 测试
        // javac -cp src/ -d dist/ src/Doraemon.java
        // java -cp dist/ Doraemon config.txt
        String configFile = args[0];
        String hwDir = args[1];
        String hwName = args[2];
        Doraemon doraemon = new Doraemon(configFile, hwDir);
        Map<String, String> comments = doraemon.writeComment(hwName);
        System.out.println(comments);
    }

}